package com.ucode.hrm.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import com.ucode.admin.base.core.CurrentLoginUserService;
import com.ucode.hrm.controller.service.ApiHrmDataPermissionService;
import com.ucode.hrm.service.HrmCustomerCompanyService;
import com.ucode.hrm.service.HrmCustomerProjectService;
import com.ucode.hrm.service.HrmEmployeeService;
import com.ucode.hrm.service.HrmResignationApplyService;
import com.ucode.model.hrm.HrmCustomerCompany;
import com.ucode.model.hrm.HrmCustomerProject;
import com.ucode.model.hrm.HrmEmployee;
import com.ucode.model.hrm.HrmResignationApply;
import com.ucode.model.hrm.convert.HrmResignationApplyConvert;
import com.ucode.model.hrm.enums.HrmEmploymentTypeEnum;
import com.ucode.model.hrm.enums.HrmSysResultCodeEnum;
import com.ucode.model.hrm.form.HrmAuditForm;
import com.ucode.model.hrm.form.HrmResignationApplyForm;
import com.ucode.model.hrm.vo.HrmResignationApplyVO;
import com.ucode.model.sys.user.AdminUser;
import com.ucode.ssm.user.service.AdminUserService;
import com.ucode.tool.annotation.DataPermission;
import com.ucode.tool.base.Paginator;
import com.ucode.tool.base.ResponseResult;
import com.ucode.tool.base.enums.GlobalResultCodeEnum;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.IdentifyUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.*;

@Tag(name = "管理后台 - 人力资源系统 - 离职申请")
@RestController
@RequestMapping("/hrm/resignation-apply")
@Validated
public class HrmResignationApplyController {

    @Resource
    private HrmCustomerProjectService customerProjectService;
    @Resource
    private HrmCustomerCompanyService  customerCompanyService;
    @Resource
    private HrmEmployeeService employeeService;
    @Resource
    private HrmResignationApplyService resignationApplyService;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private CurrentLoginUserService currentLoginUserService;
    @Resource
    private ApiHrmDataPermissionService apiHrmDataPermissionService ;

    @GetMapping("/page-list")
    @Operation(summary = "获得分页列表")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:query')")
    @DataPermission(permissions={"hrm:resignation-apply:query"})
    public ResponseResult<Paginator<HrmResignationApplyVO>> pageList(
            @Schema(description = "客户公司编码") @RequestParam(value = "customerCompanyId",required = false) Long customerCompanyId,
            @Schema(description = "客户项目编码") @RequestParam(value = "projectId",required = false) Long projectId,
            @Schema(description = "员工编号") @RequestParam(value = "employeeId",required = false) Long employeeId,
            @Schema(description = "审批状态") @RequestParam(value = "auditStatus",required = false) Integer auditStatus,
            @Schema(description = "创建时间区间",example = "[2022-07-01 00:00:00,2022-07-01 23:59:59]")  @RequestParam(value = "createTimeInterval",required = false) LocalDateTime[] createTimeInterval,
            @Schema(description = "页码",example="1") @RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
            @Schema(description = "每页记录数",example="5") @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize){

        Map<String,Object> condition = new HashMap<>();
        Set<Long> customerProjectIds = apiHrmDataPermissionService.getCurrentUserCustomerProjectIdsByDataPermission();
        //没有可查看的数据
        if(ObjUtil.isNotNull(customerProjectIds) && customerProjectIds.size() == 0){
            return ResponseResult.success(new Paginator<>());
        }

        //没有权限查看指定项目的数据
        if(ObjUtil.isNotNull(projectId) && ObjUtil.isNotNull(customerProjectIds) && !customerProjectIds.contains(projectId)){
            throw new UcodeServiceException(GlobalResultCodeEnum.UN_DATA_PERMISSION);
        }
        condition.put("projectIds",customerProjectIds);

        if(ArrayUtil.isNotEmpty(createTimeInterval) && createTimeInterval.length == 2){
            condition.put("startTime",createTimeInterval[0]);
            condition.put("endTime",createTimeInterval[1]);
        }
        condition.put("customerCompanyId",customerCompanyId);
        condition.put("projectId",projectId);
        condition.put("employeeId",employeeId);
        condition.put("auditStatus",auditStatus);
        condition.put("deltag",false);
        return ResponseResult.success(pageList(condition,pageNum,pageSize));
    }

    private Paginator<HrmResignationApplyVO> pageList(Map<String,Object> condition, int pageNum, int pageSize) {
        Paginator<HrmResignationApply> paginator = resignationApplyService.queryPageForList(condition,pageSize,pageNum);
        Paginator<HrmResignationApplyVO> paginatorVO =  HrmResignationApplyConvert.INSTANCE.convertPage(paginator);

        if(CollUtil.isNotEmpty(paginatorVO.getList())) {
            Set<Long> customerCompanyIds = new HashSet<>();
            Set<Long> projectIds = new HashSet<>();
            Set<Long> employeeIds = new HashSet<>();
            Set<Long> processorIdIds = new HashSet<>();

            for(HrmResignationApplyVO vo : paginatorVO.getList()){
                customerCompanyIds.add(vo.getCompanyId());
                projectIds.add(vo.getProjectId());
                employeeIds.add(vo.getEmployeeId());
                if(ObjUtil.isNotNull(vo.getProcessorId()) && !ObjUtil.equals(vo.getProcessorId(),0L))
                    processorIdIds.add(vo.getProcessorId());
            }

            Map<Long, HrmCustomerCompany> customerCompanyMap = customerCompanyService.getMap(customerCompanyIds);
            Map<Long, HrmCustomerProject> projectMap = customerProjectService.getMap(projectIds);
            Map<Long, HrmEmployee> employeeMap = employeeService.getMap(employeeIds);
            Map<Long, AdminUser> processorMap = adminUserService.getUserMap(processorIdIds);

            paginatorVO.getList().forEach(item -> {
                HrmCustomerCompany customerCompany = customerCompanyMap.get(item.getCompanyId());
                if(customerCompany != null)
                    item.setCompanyName(customerCompany.getCompanyName());

                HrmCustomerProject project = projectMap.get(item.getProjectId());
                if(project != null)
                    item.setProjectName(project.getProjectName());

                HrmEmployee employee = employeeMap.get(item.getEmployeeId());
                if(employee != null)
                    item.setEmployeeName(employee.getRealName());

                if(ObjUtil.isNotNull(item.getProcessorId()) && !ObjUtil.equals(item.getProcessorId(),0L)) {
                    AdminUser adminUser = processorMap.get(item.getProcessorId());
                    if(adminUser != null)
                        item.setProcessorName(adminUser.getNickname());
                }

            });
        }

        return paginatorVO;
    }

    @GetMapping("/getById/{id}")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH,example = "1024")
    @Operation(summary = "主键获得信息")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:query')")
    public ResponseResult<HrmResignationApplyVO> getById(@PathVariable(name="id",required=true) Long id){
        HrmResignationApply bean = resignationApplyService.validate(id);
        HrmResignationApplyVO vo = HrmResignationApplyConvert.INSTANCE.convert(bean);
        if(ObjUtil.isNotNull(vo.getCompanyId())){
            HrmCustomerCompany customerCompany = customerCompanyService.selectByPrimaryKey(bean.getCompanyId());
            if(customerCompany != null)
                vo.setCompanyName(customerCompany.getCompanyName());
        }

        if(ObjUtil.isNotNull(vo.getProjectId())){
            HrmCustomerProject project = customerProjectService.selectByPrimaryKey(bean.getProjectId());
            if(project != null)
                vo.setProjectName(project.getProjectName());
        }

        HrmEmployee employee = employeeService.selectBaseInfoByPrimaryKey(vo.getEmployeeId());
        if(employee != null)
            vo.setEmployeeName(employee.getRealName());

        if(ObjUtil.isNotNull(vo.getProcessorId()) && !ObjUtil.equals(vo.getProcessorId(),0L)) {
            AdminUser adminUser = adminUserService.selectByPrimaryKey(vo.getProcessorId());
            if(adminUser != null)
                vo.setProcessorName(adminUser.getNickname());
        }

        return ResponseResult.success(vo);
    }

    @PostMapping("/create")
    @Operation(summary = "创建")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:create')")
    public ResponseResult<Long> create(@Valid @RequestBody HrmResignationApplyForm form) {
        HrmResignationApply bean = HrmResignationApplyConvert.INSTANCE.convert(form);
        if(ObjUtil.isNull(bean.getEmployeeId()) || ObjUtil.equals(bean.getEmployeeId(),0L)){
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }

        HrmEmployee employee = employeeService.validate(bean.getEmployeeId());
        if(ObjUtil.equals(employee.getEmploymentType(), HrmEmploymentTypeEnum.LEFT.getCode())){
            throw new UcodeServiceException(HrmSysResultCodeEnum.EMPLOYEE_HAVE_QUITTED_ERROR);
        }

        bean.setId(IdentifyUtils.getDefaultSnowflakeId());
        bean.setProjectId(employee.getProjectId());
        bean.setCompanyId(employee.getCompanyId());
        bean.setHireDate(employee.getHireDate());

        Long id = resignationApplyService.insert(bean);
        return id != null ? ResponseResult.success(id) : ResponseResult.failed();
    }

    @PostMapping("/update/{id}")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH,example = "1024")
    @Operation(summary = "修改")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:update')")
    public ResponseResult<Object> update(@PathVariable(name="id",required=true) Long id,
                                         @Valid @RequestBody HrmResignationApplyForm form) {
        HrmResignationApply bean = HrmResignationApplyConvert.INSTANCE.convert(form);

        if(ObjUtil.isNull(bean.getEmployeeId()) || ObjUtil.equals(bean.getEmployeeId(),0L)){
            throw new UcodeServiceException(GlobalResultCodeEnum.VALIDATE_FAILED);
        }

        HrmEmployee employee = employeeService.validate(bean.getEmployeeId());
        if(ObjUtil.equals(employee.getEmploymentType(), HrmEmploymentTypeEnum.LEFT.getCode())){
            throw new UcodeServiceException(HrmSysResultCodeEnum.EMPLOYEE_HAVE_QUITTED_ERROR);
        }

        bean.setId(id);
        bean.setProjectId(employee.getProjectId());
        bean.setCompanyId(employee.getCompanyId());

        int i = resignationApplyService.update(bean);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    /**
     * 审核操作
     * @param form
     * @return
     */
    @PostMapping("/batch-audit")
    @Operation(summary = "审核")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:audit')")
    public ResponseResult<Object> batchAudit(@Valid @RequestBody HrmAuditForm form) {

        if(CollUtil.isNotEmpty(form.getIds())) {
            for(Long id : form.getIds()){
                resignationApplyService.audit(id,form.getStatuz(),currentLoginUserService.getCurrentUserId(),form.getRemark());
            }
        }
        return ResponseResult.success();
    }

    @PostMapping("/logic-delete/{id}")
    @Operation(summary = "转移到回收站")
    @Parameter(description="主键ID",name = "id", required = true,in = ParameterIn.PATH, example = "1024")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:logic-delete')")
    public ResponseResult<Object> logicDelete(@PathVariable(name="id",required=true) Long id) {
        //逻辑删除
        int i = resignationApplyService.logicDeletePrimaryKey(id);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

    @PostMapping("/batch-logic-delete")
    @Operation(summary = "批量转移到回收站")
    @PreAuthorize("@usfs.hasPermission('hrm:resignation-apply:logic-delete')")
    public ResponseResult<Boolean> batchLogicDeletePrimaryKey(@Schema(description = "编号集合",requiredMode = Schema.RequiredMode.REQUIRED)
                                                @NotEmpty(message = "编号集合为空")@Size(min = 1,max = 100,message = "编号集合数量为1-100条")
                                                @RequestParam(value = "ids",required = true) List<Long> ids) {
        int i = resignationApplyService.logicDeleteByPrimaryKeys(ids);
        return i > 0 ? ResponseResult.success() : ResponseResult.failed();
    }

}
